<!-- 
スプリッタで区切られたウィンドウ
Usage:
    <splitter_window splitter_pos="30%" direction="horizontal">
        <yield to="first_pane"></yield>
        <yield to="splitter"></yield>
        <yield to="second_pane"></yield>
    </splitter_window>


ハンドラ：
    ("splitter_pos_updated", splitterPos):
        スプリッタ位置が変化した場合に，登録したハンドラが呼ばれる
    ("update_pane_size", splitterPos):
        スプリッタ位置を外部から変更したいときに呼ぶ
-->

<splitter_window class="splitter_window">
    
    <div class="splitter_window_container" ref="container">
        <div ref="first_pane">
            <yield from="first_pane"/>
        </div>
        <div ref="splitter">
            <yield from="splitter"/>
        </div>
        <div ref="second_pane">
            <yield from="second_pane"/>
        </div>
    </div>

    <style>
        /* カスタムタグは デフォルトで inline なので block を指定してやる．
        そうしないと，width が効かない */
        splitter_window.splitter_window {
            width: 100%;
            height: 100%;
            display: block;
        }
        .splitter_window_container {
            width: 100%;
            height: 100%;
            display: flex;           /* CSS3 flexbox による配置を有効に */
            /*flex-direction: row;      コード内で指定されうる */  
            flex: auto;
        }
        div {
            position: relative;     /* ここを relative にしておかないと，子要素が外にあふれ出す */
        }
    </style>
    
    <script>
        let self = this;
        self.lastPos = 0;
        self.inDrag = false;
        // 方向
        self.isHorizontal = true;
        if ("direction" in self.opts) {
            if (self.opts.direction == "horizontal") {
                self.isHorizontal = true;
            }
            else if (self.opts.direction == "vertical") {
                self.isHorizontal = false;
            }
            else {
                console.log("Unknown direction.");
            }
        }
            

        self.on("mount", function(){
            // ドラッグ始はスプリッタ
            let splitter = self.refs.splitter;
            splitter.onmousedown = self.onMouseDown;

            // splitter 以外からも捉えられるように window に
            window.addEventListener("mousemove", self.onMouseMove);
            window.addEventListener("mouseup", self.onMouseUp);

            // ウィンドウサイズの変更
            // window 以外の要素は resizeObserver を使う必要がある
            self.resizeObserver.observe(self.refs.container);

            // スプリッタ初期位置
            let initPos = ("splitter_pos" in self.opts) ? self.opts.splitter_pos : "30%";
            if (self.isHorizontal) {
                self.refs.first_pane.style.width = initPos;
                self.refs.first_pane.style.height  = "100%";
                self.refs.splitter.style.height   = "100%";
                self.refs.second_pane.style.height = "100%";
            }
            else {
                self.refs.first_pane.style.height = initPos;
                self.refs.first_pane.style.width  = "100%";
                self.refs.splitter.style.width   = "100%";
                self.refs.second_pane.style.width = "100%";
            }

            // flex の配置
            self.refs.container.style.flexDirection = 
                self.isHorizontal ? "row" : "column";
            self.update();
        });

        self.on("unmount", function(){
            window.removeEventListener("mousemove", self.onMouseMove);
            window.removeEventListener("mouseup", self.onMouseUp);
            self.resizeObserver.disconnect();   // 全要素解放
        });


        self.onMouseDown = function(e){
            self.lastPos = self.isHorizontal ? e.clientX : e.clientY;
            self.inDrag = true;

            // クリック時に他所にフォーカスが奪われるのを防ぐ
            e.preventDefault();
        };

        self.onMouseUp = function(){
            self.inDrag = false;
        };

        self.onMouseMove = function(e){
            if (!self.inDrag) {
                return;
            }

            let container = self.refs.container;

            // ウィンドウ外にカーソルがでたときのため補正
            let containerSize = 
                self.isHorizontal ? container.offsetWidth : container.offsetHeight;
            let mousePos = self.isHorizontal ? e.clientX : e.clientY;
            let pos = Math.min(Math.max(mousePos, 0), containerSize);
            
            // 差分を求める
            let diff = pos - self.lastPos;
            self.lastPos = pos;

            // 差分を現在の幅に足す
            let first_pane = self.refs.first_pane;
            let splitterPos = 
                self.isHorizontal ? first_pane.offsetWidth : first_pane.offsetHeight;
            splitterPos += diff;
            //dispatcher.trigger(ACTION.PANE_SPLITTER_MOVE, splitterPos);

            self.UpdatePaneSize(splitterPos);
            self.trigger("splitter_pos_updated", splitterPos);
            
            //console.log(`move ${pos} ${diff} ${first_pane.offsetWidth} ${splitterPos}`);
            //console.log(`mousemove ${self.id}`);
        };

        self.resizeObserver = new ResizeObserver(   // eslint-disable-line
            () => {
                let first_pane = self.refs.first_pane;
                let splitterPos = 
                    self.isHorizontal ? first_pane.offsetWidth : first_pane.offsetHeight;
                self.UpdatePaneSize(splitterPos);
                self.trigger("splitter_pos_updated", splitterPos);
            }
        );

        self.UpdatePaneSize = function(splitterPos){

            let container = self.refs.container;
            let left = self.refs.first_pane;
            let splitter = self.refs.splitter;
            let right = self.refs.second_pane;

            // 幅
            if (self.isHorizontal) {
                left.style.width = `${splitterPos}px`;
                right.style.width = 
                    `${container.offsetWidth - splitterPos - splitter.offsetWidth}px`;
            }
            else {
                left.style.height = `${splitterPos}px`;
                right.style.height = 
                    `${container.offsetHeight - splitterPos - splitter.offsetHeight}px`;

            }
            //console.log(`update ${store.window.width} ${store.activeTab.splitterPos} ${right.offsetWidth}`);
            self.update();
        };

        self.on("update_pane_size", (splitterPos) => {
            self.UpdatePaneSize(splitterPos);
        });

    </script>
</splitter_window>

